package com.ruoyi.system.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;

/**
 * UDP 接收工具类（仅打印收到的原始数据，不处理业务）
 */
public class UdpReceiverUtil {
    // 日志记录
    private static final Logger log = LoggerFactory.getLogger(UdpReceiverUtil.class);
    // UDP 接收缓冲区大小（默认4096字节，可根据发送数据大小调整，避免数据截断）
    private static final int BUFFER_SIZE = 4096;


    /**
     * 启动 UDP 接收监听（独立线程运行，持续接收并打印原始数据）
     *
     * @param listenPort 接收端监听端口（需与发送端的 port 一致）
     */
    public void startUdpListen(int listenPort) {
        // 启动独立线程监听，避免阻塞主线程
        new Thread(() -> {
            DatagramSocket datagramSocket = null;
            try {
                // 1. 创建 UDP Socket 并绑定监听端口
                datagramSocket = new DatagramSocket(listenPort);
                log.info("UDP 接收端已启动，监听端口：{}", listenPort);

                // 2. 创建接收缓冲区和数据包对象
                byte[] receiveBuffer = new byte[BUFFER_SIZE];
                DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);

                // 3. 持续监听接收数据（阻塞式，收到数据后立即打印）
                while (!Thread.currentThread().isInterrupted()) {
                    // 接收数据（阻塞，直到收到数据包）
                    datagramSocket.receive(receivePacket);

                    // 4. 提取核心信息：发送端IP、端口、原始数据
                    String senderIp = receivePacket.getAddress().getHostAddress(); // 发送端IP
                    int senderPort = receivePacket.getPort(); // 发送端端口
                    // 提取有效数据（排除缓冲区空字节，避免打印乱码）
                    byte[] validData = new byte[receivePacket.getLength()];
                    System.arraycopy(receiveBuffer, 0, validData, 0, receivePacket.getLength());
                    String originalData = new String(validData); // 原始数据转字符串（兼容JSON/普通文本）

                    // 5. 仅打印收到的原始数据（不做任何业务处理）
                    log.info("✅ 收到 UDP 数据 -> 发送端：{}:{}，数据长度：{} 字节，原始内容：{}",
                            senderIp, senderPort, receivePacket.getLength(), originalData);

                    // 6. 重置数据包缓冲区（准备接收下一次数据）
                    receivePacket.setLength(receiveBuffer.length);
                }

            } catch (SocketException e) {
                log.error("❌ UDP 接收端启动失败，端口 {} 可能已被占用或无权限：{}", listenPort, e.getMessage());
            } catch (IOException e) {
                log.error("❌ UDP 接收数据异常：{}", e.getMessage());
            } finally {
                // 关闭Socket，释放端口
                if (datagramSocket != null && !datagramSocket.isClosed()) {
                    datagramSocket.close();
                    log.info("ℹ️ UDP 接收端已关闭，监听端口：{}", listenPort);
                }
            }
        }, "UDP-Receiver-Thread").start();
    }


    // ------------------- 测试示例 -------------------
    public static void main(String[] args) {
        // 启动 UDP 接收端，监听 11001 端口（需与发送端端口一致）
        UdpReceiverUtil receiver = new UdpReceiverUtil();
        receiver.startUdpListen(11001);
    }
}
